package com.yan.utils;

import java.io.File;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.jfinal.core.Controller;
import com.jfinal.kit.PathKit;

public class ClassUtils {

	private static final Logger logger = Logger.getLogger(ClassUtils.class);

	public static <T> List<Class<T>> scanSubClass(Class<T> pclazz) {
		return scanSubClass(pclazz, false);
	}

	public static <T> List<Class<T>> scanSubClass(Class<T> pclazz,
			boolean mustbeCanNewInstance) {
		if (pclazz == null) {
			logger.error("scanClass: parent clazz is null");
			return null;
		}

		List<File> classFileList = new ArrayList<File>();
		scanClass(classFileList, PathKit.getRootClassPath());

		List<Class<T>> classList = new ArrayList<Class<T>>();
		for (File file : classFileList) {

			int start = PathKit.getRootClassPath().length();
			int end = file.toString().length() - 6; // 6 == ".class".length();

			String classFile = file.toString().substring(start + 1, end);
			Class<T> clazz = classForName(classFile
					.replace(File.separator, "."));

			if (clazz != null && pclazz.isAssignableFrom(clazz)) {
				if (mustbeCanNewInstance) {
					//  判断是否是接口
					if (clazz.isInterface())
						continue;

					//  判断是否是abstract修饰符
					if (Modifier.isAbstract(clazz.getModifiers()))
						continue;
				}
				classList.add(clazz);
			}
		}

		return classList;
	}

	@SuppressWarnings("unchecked")
	private static <T> Class<T> classForName(String className) {
		Class<T> clazz = null;
		try {
			ClassLoader cl = Thread.currentThread().getContextClassLoader();
			clazz = (Class<T>) Class.forName(className, false, cl);
		} catch (Exception e) {
			logger.error("classForName is error", e);
		}
		return clazz;
	}

	private static void scanClass(List<File> fileList, String path) {
		File files[] = new File(path).listFiles();
		if (null == files || files.length == 0)
			return;
		for (File file : files) {
			if (file.isDirectory()) {
				scanClass(fileList, file.getAbsolutePath());
			} else if (file.getName().endsWith(".class")) {
				fileList.add(file);
			}
		}
	}

	public static <T> void main(String args[]) {
		List<Class<Controller>> list = scanSubClass(Controller.class);
		for (Class<Controller> controller : list) {

			System.out.println(controller.getName());
		}

		Class clazz = ClassUtils.class;
		//  获取User类的修饰符
		int modifier = clazz.getModifiers();

		//  判断是否是abstract修饰符
		System.out.println(Modifier.isAbstract(modifier));
		//  判断是否是接口
		System.out.println(Modifier.isInterface(modifier));
		//  获取其修饰符
		System.out.println(clazz.getModifiers());
	}
}
